using System;
using System.Collections.Generic;
using System.Text;

using System.Management.Automation;

namespace Microsoft.PowerShell.CmdletManagement
{
    [Cmdlet(VerbsCommon.Set, "PsSpecCmdletParameter", SupportsShouldProcess = true)]
    public class SetPsSpecCmdletParameterCommand : Cmdlet
    {
        [Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
        public int Id
        {
            get { return id; }
            set { id = value; }
        }
        private int id = -1;

        [Parameter(ValueFromPipelineByPropertyName=true)]
        [ValidateLength(1, 100)]
        public string Name
        {
            get { return parameterName; }
            set { parameterName = value; }
        }
        private string parameterName = null;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [AllowEmptyString]
        public string Type
        {
            get { return type; }
            set
            {
                if ((value != null) && (value.Length > 500))
                    throw new ArgumentOutOfRangeException("Type");

                type = value;
            }

        }
        private string type = null;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [AllowEmptyString]
        public string Description
        {
            get { return description; }
            set
            {
               description = value;
            }
        }
        private string description = null;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [AllowEmptyCollection]
        public string[] Alias
        {
            get { return alias; }
            set { alias = value; }
        }
        private string[] alias = null;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        public bool? AllowGlobbing
        {
            get { return allowGlobbing; }
            set { allowGlobbing = value; }
        }
        private bool? allowGlobbing;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        public bool? AllowMultiple
        {
            get { return allowMultiple; }
            set { allowMultiple = value; }
        }
        private bool? allowMultiple;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [Alias("IsDynamic")]
        public bool? Dynamic
        {
            get { return isDynamic; }
            set { isDynamic = value; }
        }
        private bool? isDynamic;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        public bool? AllowEmptyCollection
        {
            get { return allowEmptyCollection; }
            set { allowEmptyCollection = value; }
        }
        private bool? allowEmptyCollection;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        public bool? AllowEmptyString
        {
            get { return allowEmptyString; }
            set { allowEmptyString = value; }
        }
        private bool? allowEmptyString;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        public bool? AllowNull
        {
            get { return allowNull; }
            set { allowNull = value; }
        }
        private bool? allowNull;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        public int[] ValidateCount
        {
            get { return validateCount; }
            set 
            {
                if((value != null) && (value.Length != 2))
                    throw new ArgumentOutOfRangeException("ValidateCount");

                validateCount = value; 
            }
        }
        private int[] validateCount = null;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        public bool? ValidateNotNull
        {
            get { return validateNotNull; }
            set { validateNotNull = value; }
        }
        private bool? validateNotNull;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        public bool? ValidateNotNullOrEmpty
        {
            get { return validateNotNullOrEmpty; }
            set { validateNotNullOrEmpty = value; }
        }
        private bool? validateNotNullOrEmpty;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        public int[] ValidateRange
        {
            get { return validateRange; }
            set 
            {
                if ((value != null) && (value.Length != 2))
                    throw new ArgumentOutOfRangeException("ValidateRange");

                validateRange = value; 
            }
        }
        private int[] validateRange = null;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [AllowEmptyCollection]
        public string[] ValidateSet
        {
            get { return validateSet; }
            set {
                    if (value != null)
                        {
                            if (PsSpecCmdletUtils.GetStringList(value).Length > 2000)
                                throw new ArgumentOutOfRangeException("ValidateSet");
                        }
                    validateSet = value; 
                }
        }
        private string[] validateSet = null;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        public int[] ValidateLength
        {
            get { return validateLength; }
            set 
            {
                if ((value != null) && (value.Length != 2))
                    throw new ArgumentOutOfRangeException("ValidateLength");

                validateLength = value; 
            }
        }
        private int[] validateLength = null;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [AllowEmptyString]
        public string ValidatePattern
        {
            get { return validatePattern; }
            set { validatePattern = value; }
        }
        private string validatePattern = null;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [AllowEmptyString]
        public string Notes
        {
            get { return notes; }
            set { notes = value; }
        }
        private string notes = null;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [AllowEmptyString]
        public String DefaultValue
        {
            get
            {
                return defaultValue;
            }
            set
            {
                if ((value != null) && (value.Length > 200))
                    throw new ArgumentOutOfRangeException("DefaultValue");

                defaultValue = value;
            }
        }
        private string defaultValue;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [AllowEmptyString]
        public String Custom1
        {
            get
            {
                return custom1;
            }
            set
            {
                custom1 = value;
            }
        }
        private string custom1;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [AllowEmptyString]
        public String Custom2
        {
            get
            {
                return custom2;
            }
            set
            {
               custom2 = value;
            }
        }
        private string custom2;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [AllowEmptyString]
        public String Custom3
        {
            get
            {
                return custom3;
            }
            set
            {
               custom3 = value;
            }
        }
        private string custom3;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [AllowEmptyString]
        public String Custom4
        {
            get
            {
                return custom4;
            }
            set
            {
               custom4 = value;
            }
        }
        private string custom4;

        [Parameter(ValueFromPipelineByPropertyName = true)]
        [AllowNull]
        [AllowEmptyString]
        public String HelpDescription
        {
            get
            {
                return helpDescription;
            }
            set
            {
               helpDescription = value;
            }
        }
        private string helpDescription;

        [Parameter(Mandatory = false)]
        public String ServiceUri
        {
            get
            {
                return _serviceUri;
            }
            set
            {
                _serviceUri = value;
            }
        }
        private string _serviceUri = PsSpecCmdletUtils.Constants.ServiceUri;

        protected override void ProcessRecord()
        {
            // Check that they've specified a parameter name
            if (!PsSpecCmdletUtils.IsValidParameterName(Name))
            {
                WriteError(new ErrorRecord(
                    new Exception(resources.InvalidParameterName),
                    "INVALID_PARAMETER_NAME",
                    ErrorCategory.InvalidArgument, Name));
                return;
            }

            if (ShouldProcess(
                String.Format("{0}", ServiceUri),
                String.Format(resources.SetPsSpecCmdletParameterShouldProcess, id)))
            {
                PsSpecCmdletService.CmdletService service =
                    new PsSpecCmdletService.CmdletService();
                service.Url = ServiceUri;
                service.UseDefaultCredentials = true;

                try
                {
                    service.UpdatePsSpecCmdletParameter(Id, Name, Type,
                        Description, PsSpecCmdletUtils.GetStringList(Alias), 
                        AllowGlobbing,
                        AllowMultiple, Dynamic, AllowEmptyCollection, AllowEmptyString, AllowNull, PsSpecCmdletUtils.GetStringList(ValidateCount),
                        ValidateNotNull, ValidateNotNullOrEmpty, PsSpecCmdletUtils.GetStringList(ValidateRange), PsSpecCmdletUtils.GetStringList(ValidateSet),
                        PsSpecCmdletUtils.GetStringList(ValidateLength), ValidatePattern, Notes,
                        DefaultValue, Custom1, Custom2, Custom3, Custom4, HelpDescription);
                }
                catch (System.Web.Services.Protocols.SoapException e)
                {
                    WriteError(new ErrorRecord(e, "CMDLET_SERVICE_ERROR",
                                                ErrorCategory.InvalidOperation,
                                                String.Format(resources.SetPsSpecCmdletParameterShouldProcess,
                                                    Id)));
                }
            }
        }
    }
}
